package com.kt.thread.demo;

/**
 * Created by tangwy on 2016/1/11.
 * 一道面试题:
 * 子线程循环10次，接着主线程循环100次，接着又回到子线程循环10次，接着再回到主线程循环100次，
 * 如此循环50次，请写出程序。
 * 该题要点：
 * 1、当主线程或子线程执行时，应不出现干扰情况，如子线程执行一半就退出，所以应该使用代码互斥，保证完整执行。
 * 2、题目要求子线程执行完后，主线程执行，然后又是子线程，依此论推，所以要保证子线程和主线程依次执行，
 * 而不是某一个线程一直执行好几次，所以要使用等待与唤醒机制
 */
public class Exercises {
    //定义一个变量实现等待与唤醒
    private boolean run = true;

    private int i = 0;

    /**
     * 子线程，使用synchronized互斥
     *
     * @param i
     */
    public synchronized void sub(int i) {
        while (!run) {
            try {
                this.wait();//等待
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        for (int j = 1; j <= 10; j++) {
            System.out.println("子线程第" + i + "次执行,j=" + j);
        }
        run = false;
        this.notify();//通知其他等待的线程执行
    }

    /**
     * 主线程，使用synchronized互斥
     *
     * @param i
     */
    public synchronized void main(int i) {
        while (run) {
            try {
                this.wait();//等待
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        for (int j = 1; j <= 20; j++) {
            System.out.println("主线程第" + i + "次执行,j=" + j);
        }
        run = true;
        this.notify();
    }

    /**
     * 习题：创建四个线程，两个自增，两个自减
     */
    /**
     * 自增方法
     */
    private synchronized void Add() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    i++;
                    System.out.println("Add,ThreadName=" + Thread.currentThread().getName() + ",i=" + i);
                }
            }
        }).start();
    }

    /**
     * 自减
     */
    private synchronized void Jian() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    i--;
                    System.out.println("Jian,ThreadName=" + Thread.currentThread().getName() + ",i=" + i);
                }
            }
        }).start();
    }

    public void run() {
        Add();
        Jian();
    }
}
